/*
 Автор: Швейкин Евгений Юрьевич

 Функциональное описание:
    Имитатор АЦП
*/
`timescale 1ns / 10ps
//    ********************** НАЧАЛО МОДУЛЯ *********************************************************
module mod_adc_im
    #(  parameter freq_p        = 100_000_000,
        parameter col_p         = 320,
        parameter row_p         = 240
    )
    (   input  logic            reset_n,
        input  logic            clk,

        input  logic            vldata_i,
        input  logic            vhdata_i,
        input  logic            vrdata_i,
        input  logic            vclamp_i,
        
        input  logic            vlsync_i,   // Синхроимпульсы
        input  logic            vrsync_i,
        input  logic            vhsync_i,
        
        input  logic [15:0]     matrix_data,

        output logic [15:0]     data_o,
        output logic [31:0]     data_addr_o,
        output logic            data_wre_o,

        output logic [9:0]      col,
        output logic [9:0]      row
        
    );

//    ********************* КОНСТАНТЫ **************************************************************
    localparam int     adc_width_lp             = 14;
    
//    ********************* СОЗДАНИЕ И ОПИСАНИЕ ПЕРЕМЕННЫХ *****************************************
    
    logic [15:0]    background_cnt;
    logic [15:0]    background_latch;
    logic [31:0]    data;
    
    logic           vhsync_0;
    logic           vhsync_1;
    logic           vhsync_fall;
    logic           vhsync_rise;

    logic           vhdata_0;
    logic           vhdata_1;
    logic           vhdata_rise;   

    logic           vclamp_0;
    logic           vclamp_1;
    logic           vclamp_fall;
    logic           vclamp_rise;  
    

//  ********************* БЛОК НЕПРЕРЫВНЫХ НАЗНАЧЕНИЙ ASSIGN ***************************************


//  ********************* ОПИСАНИЕ ПРОЦЕССОВ *******************************************************

    always_ff @(posedge clk)
    begin
        if (vhdata_i)
            col <= 10'd0;
        else if (vhsync_fall)
            col <= col + 10'd1;
        else;
        
        if (vrdata_i)
            row <= -10'd1;
        if (vhdata_rise)
            row <= row + 10'd1;
        else;
    end

    always_ff @(posedge clk)
    begin
        vhsync_0     <= vhsync_i;
        vhsync_1     <= vhsync_0;
        vhsync_fall  <= vhsync_1 & (~vhsync_0);
        vhsync_rise  <= vhsync_0 & (~vhsync_1);
        
        vhdata_0     <= vhdata_i;
        vhdata_1     <= vhdata_0;
        vhdata_rise  <= vhdata_0 & (~vhdata_1);
        
        vclamp_0     <= vclamp_i;
        vclamp_1     <= vclamp_0;
        vclamp_fall  <= vclamp_1 & (~vclamp_0);
    end

   
    always_ff @(posedge clk)
    begin
        data_addr_o     <= col + row * col_p;
        if(vhsync_rise) begin
            data[15:0]  <= matrix_data;
        end
        else;
    end

    always_ff @(posedge clk)
    begin
        data_wre_o  <= vclamp_fall;
        if (vclamp_i) begin
            data_o  <= 2**adc_width_lp - 1;
        end
        else begin
            data_o <= matrix_data;
        end
    end
    
    
endmodule